<?php
/**
 * Created by sublime 3.
 * Auth: Inhere
 * Date: 14-9-28
 * Time: 10:35
 * Uesd: 主要功能是 hi
 * AbstractBase.php
 */
namespace ulue\core\abstracts;

use Ulue;

abstract class AbstractBase extends AbstractCore
{
    /**
     * 给当前实例定义ID, 若没有定义 则返回完整类名
     * @var string
     */
    private $id;

    /**
     * request name
     * @var string
     */
    private $name;

    /**
     *  classname|filename , no namespace
     * @var string
     */
    private $className;

    /**
     * show name  e.g. When used in bread crumbs
     * @var string
     */
    private $showName  = null;

    /**
     * current [module|controller|view(action)] dir path
     * @var string
     */
    private $path;

    /**
     * current [module|controller|view(action)] request route string
     * @var string
     */
    private $route = '/';

    // public function __construct()
    // {
    //     $this->getId();
    //     $this->getClassName();
    // }

    /**
     * isAllowCall description
     * @extends AbstractCore::isAllowCall
     * @param  [type]  $method [description]
     * @return boolean         [description]
     */
    protected function isAllowCall($method)
    {
        $filters = $this->filters();

        # 用户 ...
        if (isset($filters['users']) && ($users = $filters['users'])) {
        }

        # 用户角色 ...
        if (isset($filters['roles']) && ($roles = $filters['roles'])) {
        }

        return parent::isAllowCall($method);
    }

    /**
     * [filters 过滤请求]
     * @extends AbstractCore::isAllowCall
     * @return array [type] [description]
     */
    protected function filters()
    {
        /*
        return [
          'deny'  => 'method1,method2, ...',
          'allow' => 'method1,method2, ...',
          'users' => 'user1,user2, ...',
          'roles' => 'admin,editor, ...',
        ]
         */
        return [];

    }

    /**
     * 可选的检查 类 类文件 父类
     * @param $fullPath
     * @param $fullClass
     * @param $parentClass
     * @param string $title
     * @throws \DRuntimeException
     */
    protected function checkIsCorrectClass($fullPath, $fullClass, $parentClass, $title='xxx')
    {
        # 检查文件是否存在
        if ($fullPath && !file_exists($fullPath) ) {
            throw new \DRuntimeException(Ulue::tl('Requested file [{file}] does not exist!',['{file}'=>$fullPath]));
        }

        # 检查文件中类是否存在(会自动加载类)
        if ( $fullClass && !class_exists($fullClass) ) {
            throw new \DRuntimeException( Ulue::tl('File {file} there is no corresponding class [{class}]', [
                '{file}'  => $fullPath,
                '{class}' => $fullClass
                ] )
            );
        }

        # 必须继承自某个基类
        if ( $parentClass && !is_subclass_of($fullClass, $parentClass) ) {
            throw new \DRuntimeException(Ulue::tl(
                'Class [{class}] must directly or indirectly inherits a base class "{parentClass}"',
                [
                    '{class}' => $fullClass,
                    '{parentClass}' => $parentClass
                ] )
            );
        }
    }


    /**
     * Sets the 给当前实例定义ID, 若没有定义 则返回完整类名.
     *
     * @param string $id the id
     *
     * @return self
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * @see  self::fullname()
     * @return string ID of the object,a has namespace's classname
     */
    public function getId()
    {
        if (!$this->id) {
            $this->id = self::fullname();
        }

        return $this->id;
    }


    /**
     * Sets the request name.
     *
     * @param string $name the name
     *
     * @return self
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    public function getName()
    {
        return $this->name;
    }


    /**
     * Sets the classname|filename , no namespace.
     *
     * @param string $className the classname
     *
     * @return self
     */
    public function setClassName($className)
    {
        $this->className = $className;

        return $this;
    }

    /**
     * @see self::className()
     * @return string
     */
    public function getClassName()
    {
        if (!$this->className) {
            $this->className = self::className();
        }

        return $this->className;
    }

    public function getFullName()
    {
        return $this->getId();
    }

    /**
     * Sets the show name  e.g. When used in bread crumbs.
     *
     * @param string $showName the show name
     *
     * @return self
     */
    public function setShowName($showName)
    {
        $this->showName = trim($showName);

        return $this;
    }

    public function getShowName()
    {
        if ( !$this->showName ) {
            $this->showName = $this->name;
        }

        return $this->showName;
    }

    /**
     * Sets the current [module|controller|view(action)] dir path.
     *
     * @param string $path the path
     *
     * @return self
     */
    public function setPath($path)
    {
        if (!is_dir($path)) {
            throw new \DRuntimeException("请设置一个存在的目录路径");
        }

        $this->path = $path;

        return $this;
    }

    /**
     * @return string the called class file dir path
     */
    public function getPath()
    {
        if (!$this->path) {
            $class       = new \ReflectionClass($this);
            $this->path  = dirname($class->getFileName());
        }

        return $this->path;
    }

    /**
     * 获取文件全路径
     * @return $this
     */
    public function getFile()
    {
        $file = $this->path .'/'.sefl::className(). '.php';

        return $file;
    }

    /**
     * Sets the current [module|controller|view(action)] request route string.
     *
     * @param string $route the route
     *
     * @return self
     */
    public function setRoute($route)
    {
        $this->route = $route;

        return $this;
    }

    public function getRoute($full=false)
    {
        if ($full) {
            return \Ioc::get('app.uri')->getRoot().'/'.$this->route;
        }

        return $this->route;
    }
}